# -*- coding: utf-8 -*-


from typing import List
from jenkins import Jenkins, JenkinsException
from conf.entity.module.git_config import JenkinsConfig, GitProject, GitBranchPair, GitConfig


class JenkinsOperation:
    user_account: str
    user_password: str
    git_config: GitConfig
    jenkins_config: JenkinsConfig
    server_instance: Jenkins

    def __init__(self, git_config: GitConfig):
        self.git_config = git_config
        self.jenkins_config = git_config.jenkins_config
        if self.jenkins_config is None:
            return
        ldap_config = self.jenkins_config.ldap_config
        if ldap_config is None:
            raise BaseException('init JenkinsOperation failed, no LDAP config')
        self.user_account = ldap_config.user_account
        self.user_password = ldap_config.user_password

        self.server_instance = Jenkins(self.jenkins_config.base_url,
                                       username=str(self.user_account),
                                       password=str(self.user_password))

    def _no_jenkins_op(self, git_project: GitProject) -> bool:
        if self.jenkins_config is None:
            return True
        if self.jenkins_config.force_deploy:
            return False

        if git_project.jenkins_job == "" or not self.jenkins_config.do_deploy:
            print('no need to deploy Jenkins job, deDeploy switch is off or jenkins job is empty')
            return True

        branch_merged = False
        if self.git_config.merge_up and git_project.merged_up:
            branch_merged = True
        if self.git_config.merge_down and git_project.merged_down:
            branch_merged = True
        if not branch_merged:
            print('no need to deploy Jenkins job, branch not merged')
            return True

        return False

    @staticmethod
    def _get_job_names(branch_pair: GitBranchPair, git_project: GitProject):
        job_names = []
        job_adapters = branch_pair.jenkins_job_adapters
        if len(job_adapters) > 0:
            for adapter in job_adapters:
                job_names.append(adapter.prefix + git_project.jenkins_job + adapter.suffix)
        else:
            job_names.append(git_project.jenkins_job)
        return job_names

    def get_jobs(self, git_project: GitProject, job_names: list) -> List:
        job_info_list = []
        if self._no_jenkins_op(git_project):
            return job_info_list
        try:
            for job_name in job_names:
                job_info = self.server_instance.get_job_info(job_name)
                job_info_list.append(job_info)
        except JenkinsException as e:
            print(f'failed to get Jenkins job info: ', e)
        return job_info_list

    def build_job_if_need(self, branch_pair: GitBranchPair, git_project: GitProject):
        if self._no_jenkins_op(git_project):
            return

        job_names = self._get_job_names(branch_pair, git_project)
        job_info_list = self.get_jobs(git_project, job_names)
        if len(job_names) != len(job_info_list):
            print(f'job_names size: {len(job_names)} not match job_info_list size: {len(job_info_list)}')
            return
        if len(job_info_list) > 0:
            try:
                for job_name in job_names:
                    build_queue = self.server_instance.build_job(job_name)
                    git_project.jenkins_deployed = True
                    print(f'build Jenkins job {job_name} successfully, build queue: {build_queue}')
            except JenkinsException as e:
                print(f'failed to build Jenkins jobs {job_names}, error: {e}')
